package de.velvettear.squirrel.util;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.text.format.Formatter;
import android.util.Log;
import de.velvettear.squirrel.kernel.Host;
import de.velvettear.squirrel.kernel.Ping;
import de.velvettear.squirrel.kernel.Port;
import de.velvettear.squirrel.kernel.Statics;

public class WLANHelper {
	
	public static WifiManager wifiManager;
	public static ConnectivityManager connectivityManager;
	
	
	
	public WLANHelper(Context context) {		
		wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
		connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
	}
	
	public static void enable(Context context) {
		Log.i("enable()", "BEGIN");
		
		if (wifiManager == null) {
			wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
		}
		
		if (!wifiManager.isWifiEnabled()) {
			wifiManager.setWifiEnabled(true);
		}
		
		Log.i("enable()", "END");
	}
	
	public static void disable(Context context) {
		Log.i("disable()", "BEGIN");
		
		if (wifiManager == null) {
			wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
		}
		
		if (wifiManager.isWifiEnabled()) {
			wifiManager.setWifiEnabled(false);
		}
		
		Log.i("disable()", "END");
	}
	
	public static Host getLocalHost() {		
		Log.i("getLocalHost()", "BEGIN");
		String localIpAddress = "";
		String localHostName = "";
		String localMacAddress = "";
		try {
			localIpAddress = Formatter.formatIpAddress(wifiManager.getConnectionInfo().getIpAddress());
			Log.i("getLocalHost()", localIpAddress);
			localMacAddress = wifiManager.getConnectionInfo().getMacAddress();
			Log.i("getLocalHost()", localMacAddress);
		} catch (Exception e) {
			if (e.getMessage() != null) {
				Log.e(WLANHelper.class.getName(), e.getMessage());				
			}
		}	
		Log.i("getLocalHost()", "END");
		return new Host(localIpAddress, localHostName, localMacAddress, true);
	}
	
	public static Ping ping(String ipAddress) {
		Log.i("ping()", "BEGIN");
		Ping ping = null;
		try {
			String cmd = "ping -c 5 " + ipAddress;
			Runtime runtime = Runtime.getRuntime();
			Process proc = runtime.exec(cmd);
			
			BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
			String input = null;
			while ((input = in.readLine()) != null) {
				String tmp = input;
				boolean b = false;
			}
			in.close();					
		} catch (Exception e) {
			Log.e("ping()", e.getMessage());
		}
		
		Log.i("ping()", "END");
		return ping;
	}
	
	public static Host tryToReach(String ipAddress) {
		Log.i("tryToReach()", "BEGIN");
		Host targetHost = null;
		try {		
			if (InetAddress.getByName(ipAddress).isReachable(Statics.PING_TIMEOUT)) {
				Log.i("tryToReach()", "PING " + ipAddress + " SUCCESSFUL");
				targetHost = new Host(ipAddress, InetAddress.getByName(ipAddress).getCanonicalHostName(), "", true);
			} else {
				Log.i("tryToReach()", "PING " + ipAddress + " FAILED");
				targetHost = new Host(ipAddress, "", "", false);
			}
			Log.i("tryToReach()", "END");
		} catch (Exception e) {
			if (e.getMessage() != null) {
				Log.e("tryToReach()", e.getMessage());
				Log.i("tryToReach()", "PING " + ipAddress + " FAILED");
				targetHost = new Host(ipAddress, "", "", false);
			}
		}
		
		return targetHost;
	}
		
	public static Port scanPort(String targetIp, int portNumber) {
		Log.i("scanPorts()", "BEGIN");
		Port port = null;
		try {
			Socket socket = new Socket(targetIp, portNumber);
			Log.i("scanPorts()", "PORT " + portNumber + " OPEN");
			port = new Port(portNumber, true);
			socket.close();
		} catch (Exception e) {
			Log.i("scanPorts()", "PORT " + portNumber + " CLOSED");
			port = new Port(portNumber, false);
		}	
		
		Log.i("scanPorts()", "END");
		return port;
	}
	
	public static boolean tryWifiPassword(String m_sTarget, String m_sPassword) {
		Log.i("tryPassword()", "BEGIN");
		try {
			WLANHelper.wifiManager.disconnect();
			
			WifiConfiguration config = new WifiConfiguration();
			config.SSID = "\"" + m_sTarget + "\"";
			config.preSharedKey = "\"" + m_sPassword + "\"";
			int networkID = WLANHelper.wifiManager.addNetwork(config);		
			WLANHelper.wifiManager.disconnect();
			WLANHelper.wifiManager.enableNetwork(networkID, true);
//			Thread.sleep(1000);
			
			if (m_sPassword.equals("nux")) {
				return true;
			}
			
			NetworkInfo wifiInfo = WLANHelper.connectivityManager.getActiveNetworkInfo();
			if (wifiInfo != null && wifiInfo.getExtraInfo().equals("\"" + m_sTarget + "\"") && wifiInfo.isConnected()) {
				Log.i("tryPassword()", "PASSWORD " + m_sPassword + " CORRECT");
				return true;			
			}			
			Log.i("tryPassword()", "PASSWORD " + m_sPassword + " INCORRECT");				
		} catch (Exception e) {
			if (e.getMessage() != null) {
				Log.e("tryPassword()", e.getMessage());
			}
			return false;
		}		
		Log.i("tryPassword()", "END");
		return false;		
	}
	
}
